package me.zzp.configuration;

import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;

/**
 * @author zhangzepeng
 */
@Configuration
public class MyBatisConfiguration {

    @Bean
    public DataSource getDataSource() throws Exception {
        PooledDataSource dataSource = new PooledDataSource();
        dataSource.setDriver("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:");

        // create tables
        try (Connection connection = dataSource.getConnection()) {
            try (PreparedStatement call = connection.prepareStatement("create table users (id integer auto_increment primary key, name varchar(64), version integer default 1)")) {
                call.execute();
            }
        }

        return dataSource;
    }

    @Bean
    public SqlSessionFactory getSqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        SqlSessionFactory factory = bean.getObject();

        org.apache.ibatis.session.Configuration configuration = factory.getConfiguration();
        configuration.setCacheEnabled(true);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setUseGeneratedKeys(true);

        TypeAliasRegistry typeAliases = configuration.getTypeAliasRegistry();
        typeAliases.registerAliases("me.zzp.model");

        return factory;
    }

    @Bean
    public MapperScannerConfigurer getMapperScannerConfigurer() {
        MapperScannerConfigurer scanner = new MapperScannerConfigurer();
        scanner.setBasePackage("me.zzp.mapper");
        return scanner;
    }

    /* transaction manager */

    @Bean
    public PlatformTransactionManager getTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
